#ifndef _LIB_TASK
#define _LIB_TASK
#include "page.module.js"
#include "prefs.module.js"
#include "boss.module.js"
#include "console.module.js"
#include "ajax.lib.js"
#include "utility.lib.js"
#include "usolib.lib.js"

var Task = {
	leveling: false,
	level_ajax: false,
	level: function(html) {
		if (Boss.leveling) {
			return;
		}
		Boss.leveling = true;
		var array = [{
			name: 'Attack',
			action: 'attack',
			aim: Settings.level_attack,
			current: null,
			difference: null
		},
		{
			name: 'Defence',
			action: 'defense',
			aim: Settings.level_defence,
			current: null,
			difference: null
		},
		{
			name: 'Energy',
			action: 'energy_max',
			aim: Settings.level_energy,
			current: null,
			difference: null
		},
		{
			name: 'Health',
			action: 'health_max',
			aim: Settings.level_health,
			current: null,
			difference: null
		},
		{
			name: 'Stamina',
			action: 'recovery_max',
			aim: Settings.level_stamina,
			current: null,
			difference: null
		}],
			result = html.match(new RegExp('<td>([0-9].*?)</td>', 'g')),
			aim_ratio_total = 0,
			ratio_total = 0,
			re = new RegExp('<td>(.*?)</td>'),
			j = 0;

		Boss.exp_points = 0;
		if (match = html.match(new RegExp('You have <b>([0-9]+)<'))) {
			Boss.exp_points = Utility.make_number(match[1]);
		}
		for (var i = 0; i < array.length; i++) {
			if (array[i].aim == 0) {
				array.remove(i);
				i--;
			} else {
				array[i].current = parseInt(result[j].match(re)[1], 0);
				aim_ratio_total += array[i].aim;
				ratio_total += array[i].current;
			}
			j++;
		}
		if (!array.length > 0) {
			Boss.leveling = false;
			Settings.level = false;
			return;
		}
		for (i = array.length - 1; i >= 0; i--) {
			aim_ratio = array[i].aim / aim_ratio_total;
			ratio = array[i].current / ratio_total;
			array[i].difference = aim_ratio - ratio;
		}
		array = array.sort(function(a, b) {
			return b.difference - a.difference;
		});
		var fn = function() {
			Boss.leveling = false;
		};
		if (array[0].name == "Stamina" && 2 > Boss.exp_points) {
			setTimeout(fn, 300000);
			return;
		}
		Console.log([{
			name: 'Script',
			value: 'Level'
		},
		{
			name: 'Action',
			value: 'Raising Boss\'s ' + array[0].name
		}]);
		Task.level_ajax = true;
		Ajax(Page.domain + '/mobwars/profile/do.php?action=increase&type=' + array[0].action, function(xhr) {
			Page.captcha(xhr.responseText);
			if (Page.pausing === true)
				return;
			Task.announce(xhr.responseText);
			Task.level_ajax = false;
			Boss.leveling = false;
			Boss.update(xhr.responseText);
		});
		fn = function() {
			if (Task.level_ajax) {
				Task.level_ajax = false;
				Boss.leveling = false;
			}
			return;
		};
		setTimeout(fn, 20000);
	},
	bank: function(cb) {
		Cache.banking = true;
		if (cb) {
			Cache.bank_cb = cb;
		}
		Ajax(Page.domain + '/mobwars/bank/do.php?action=deposit&deposit_amount=' + Boss.cash, function(xhr) {
			Page.captcha(xhr.responseText);
			if (Page.pausing === true) {
				Page.pause_cb(function() {
					Task.bank();
					return;
				});
				return;
			};
			Cache.banking = false;
			Boss.update(xhr.responseText);
			Cache.bank_cb();
			return;
		},
		'POST');
		return;
	},
	heal: function(cb) {
		Cache.healing = true;
		if (cb) {
			Cache.heal_cb = cb;
		}
		Ajax(Page.domain + '/mobwars/hospital/do.php?action=heal', function(xhr) {
			Page.captcha(xhr.responseText);
			if (Page.pausing === true) {
				Cache.heal_v = false;
				Page.pause_cb(function() {
					Task.heal();
				});
				return;
			};
			Boss.update(xhr.responseText);
			if (Boss.health >= Settings.max_health) {
				Cache.healing = false;
				Cache.heal_cb();
				return;
			}
			Task.heal();
		});
	},
	announce: function(html) {
		if (match = html.match(new RegExp('<div.*?class="announcement".*?>(?:.|\\s)*?</div></div>')))
			html = match[0];

		var are = new RegExp('<span class="announceTitle">(.*?)</span>((?:.|\\s)*)</div>'),
			b_re = new RegExp('claimed the bounty of (\\$[0-9]{1,4}(?:,[0-9]{3})*?)\\.'),
			bounty = false,
			bounty_win = 0;

		if (divh = html.match(are)) {
			Console.announce({
				title: divh[1],
				content: divh[2]
			});
		}
		if (m = html.match(b_re)) {
			bounty = true;
			bounty_win = Utility.make_number(m[1]);
			Cache.tb++;
			document.getElementById('mwt_bount').textContent = Cache.tb;
		}
		if ( m = html.match( /You won the fight, taking (\d+?) damage and dealing (\d+?) damage to your enemy.*?You gained (.+?) and (\d+?) experience/ ) ) {
			var dr = parseInt(m[1], 0),
				dd = parseInt(m[2], 0),
				cash = Utility.make_number(m[3]) + bounty_win,
				exp = parseInt(m[4], 0);

			Cache.tdd += dd;
			Cache.tdr += dr;
			Cache.texp += exp;
			Cache.tw += cash;
			Cache.twins++;
			document.getElementById('mwt_damaged').textContent = Cache.tdd;
			document.getElementById('mwt_damager').textContent = Cache.tdr;
			document.getElementById('mwt_won').textContent = Utility.int_dollars(Cache.tw);
			document.getElementById('mwt_exp').textContent = Cache.texp;
			document.getElementById('mwt_wins').textContent = Cache.twins;
			return {
				bounty: bounty,
				won: true,
				lost: false,
				damager: dr,
				damaged: dd,
				cash_str: m[3],
				cash: cash,
				exp: exp
			};
		}
		if ( m = html.match( /lost the fight, taking (\d+?) damage and dealing (\d+?) damage/ ) ) {
			var damager = parseInt(m[1], 0),
				damaged = parseInt(m[2], 0);

			Cache.tdd += damaged;
			Cache.tdr += damager;
			Cache.tw += bounty_win;
			document.getElementById('mwt_damaged').textContent = Cache.tdd;
			document.getElementById('mwt_damager').textContent = Cache.tdr;
			document.getElementById('mwt_won').textContent = Utility.int_dollars(Cache.tw);
			return {
				bounty: bounty,
				cash: bounty_win,
				won: false,
				lost: true,
				damager: damager,
				damaged: damaged
			};
		}
		var re = new RegExp('<div class="error">(.*?)<br');
		if (m = html.match(re)) {
			return {
				won: false,
				lost: false,
				captcha: false,
				message: m[1]
			};
		}
		return null;
	},
	chain_check: function( html, fn ) {
		var doc = document.createElement('div'),
			feed = {},
			array = [],
			key,
			c_user = [],
			item;
		doc.innerHTML = html; // Parse HTML

		// Grab news feed items only with negative association. E.g. do damage to our boss
		$( "//div[@class='feedItem' and (contains(.,' second') or contains(.,' minute') or contains(.,' hour')) and " +
				"(contains(.,'fight') or contains(.,'hitlist') or contains(.,'punched'))]", doc ).each(function( i ) {
			var time_match = this.textContent.match( /(\d+) (second|minute|hour)s? ago/ ),
				feed_item = {
					user_id: parseInt( $("//a[contains(@href,'user_id=')]", this)[0].href.match( /user_id=(\d+)/ )[1] ),
					type: this.textContent.match( /(fight|hitlist|punch)/ )[1],
					time: time_match[2] === "hour" ?
						parseInt( time_match[1] ) * 60 * 60 :
						time_match[2] === "minute" ? parseInt( time_match[1] ) * 60 : parseInt( time_match[1] ),
					iteration: i
				};
			if ( feed[ feed_item.user_id ] instanceof Array )
				feed[ feed_item.user_id ].push( feed_item );
			else
				feed[ feed_item.user_id ] = [ feed_item ];
		});
		doc = html = null; // Clear some memory

		// Now we need to check if they chained
		for ( key in feed ) {
			c_user = [ feed[ key ][0] ];

			for ( var i = 1, feed_item; feed_item = feed[ key ][ i ]; i++) {
				if ( 1 < feed_item.time / Settings.chain_time ) { // We are in in-accurate feed stages
					if ( feed_item.iteration - feed[ key ][ i - 1 ].iteration <= 3 )
						c_user.push( feed_item );
					else
						c_user = [ feed_item ];
				}
				else { // We are in normal feed stages
					if ( feed_item.time - c_user[0].time <= Settings.chain_time ) { // We are good
						item = null;
						c_user.push( feed_item );
					}
					else
						c_user = [ feed_item ];
				}

				if ( c_user.length >= Settings.chain_attacks ) {
					array.push( key );
					if ( typeof fn === "function" )
						fn( key );
					break;
				}
			}
		}
		return array;
	}
};
#endif
